local japi = require 'jass.japi'

local textarea = {}
setmetatable(textarea, textarea)

--- 存放各种文本域
textarea.alltextareas = {}

local mt = extends(class.panel){}

-- 类型
mt.type = 'textarea'

-- 文本行间距
mt.linegrap = 12

-- 文本边距
mt.lineinset = 16

-- 行数上限
mt.maxlines = 32

-- 滚动幅度
mt.step_value = 0.10

-- 字体
mt.font = 'fonts\\font.ttf'

-- 字体大小
mt.font_size = 10

-- 图像路径
mt.normal_image = '11'

--- 创建控件
function mt.new(parent, x, y, w, h)
    return class.textarea:builder
    {
        parent = parent,
        w = w,
        h = h,
        x = x,
        y = y,
    }
end 

-- 初始化
function mt:init()
    if self.handle then return end
    
    class.panel.init(self)
    self:set_view_port(true)
    if package.local_test then 
        local info = debug.getinfo(5, "Sl") or {}
        local bool = info.short_src:find('core')
        --- 不是底层创建的控件记录路径用来热更新
        if not bool then 
            self._src = info.short_src
            self._line = info.currentline
        end 
    end 
    self._lines = {}    -- 字体控件列表
    self._texts = {}    -- 文本栈
    self._scroll = 1.0
    self._currentlines = 0
    self._backdrop = class.panel:builder{parent = self}
    self._backdrop:set_normal_image('')
    for i = 1, self.maxlines do 
        self._lines[i] = class.text:builder{
            parent = self._backdrop,
            w = self.w - (self.lineinset * 2),
            h = 0,
            x = self.lineinset,
            y = 0,
            outline = true,
            font = self.font,
            font_size = self.font_size,
            flags = '禁用换行符',
        }
        self._lines[i]:hide()
    end 
    textarea.alltextareas[self.handle] = self
    return self
end 

-- 设置宽度
function mt:set_width(width)
    if self.removed then return end
    if self._backdrop then 
        self._backdrop:set_width(width)
    end 
    if self._lines then 
        for i = 1, self.maxlines do 
            self._lines[i]:set_width(width - (self.lineinset * 2))
        end 
    end 
    class.panel.set_width(self, width)
    self:update()
end 

-- 删除
function mt:remove()
    if self.removed then return end 
    for i = 1, self.maxlines do 
        self._lines[i]:remove()
    end 
    textarea.alltextareas[self.handle] = nil
    self._backdrop:remove()
    class.panel.remove(self)
end 

-- 添加文本
function mt:add_text(text)
    if not text then return end 
    -- 如果行号超过最大行则 踢掉第一行
    if self._currentlines >= self.maxlines then 
        table.remove(self._texts, 1)
        local line = self._lines[1]
        for i = 1, self.maxlines - 1 do 
            self._lines[i] = self._lines[i+1]
        end
        self._lines[self.maxlines] = line
    else 
        self._currentlines = self._currentlines + 1
    end 
    self._texts[self._currentlines] = text
    self._lines[self._currentlines]:set_text(text)
    self:update()
end

--- 设置当前值
function mt:set_scroll(value)
    if self.removed then return end
    local scroll = math.limit(value, 0.00, 1.00)
    local height = self._backdrop:get_height()
    local heightmax = self:get_height()
    if height <= heightmax then 
        scroll = 1.0
    end 
    self._scroll = scroll
    self._backdrop:set_position(0, -scroll * (height - heightmax))
end 

--- 获取当前值
function mt:get_scroll()
    return self._scroll
end

function mt:update()
    if not self._backdrop then 
        return 
    end
    local grap = self.linegrap / 2
    for i = 1, self.maxlines do
        if i > self._currentlines then 
            self._lines[i]:hide()
        else 
            self._lines[i]:set_position(self.lineinset, grap)
            self._lines[i]:show()
            grap = grap + self._lines[i]:get_height() + self.linegrap
        end 
    end 
    self._backdrop:set_height(math.max(grap ,self:get_height()))
    self:set_scroll(1.0)
end 

--清空文本
function mt:clear_all_texts()
    self._texts = {}
    self._currentlines = 0
    for i = 1, self.maxlines do 
        self._lines[i]:hide()
    end 
    self:update()
end 

--- 事件注册
textarea.events = {
    --- 鼠标滚轮滚动
    [-1] = function(_, just)
        if ac.game:is_active() then 
            local focus 
            local index = 0
            for handle, frame in pairs(textarea.alltextareas) do 
                if not frame.removed and frame:has_mouse() and frame:is_absolute_show() then 
                    if not focus or frame._index > index then 
                        focus = frame
                        index = frame._index
                    end 
                end
            end 
            if focus then 
                local scroll = focus._scroll
                if just == true then 
                    scroll = scroll - focus.step_value
                else 
                    scroll = scroll + focus.step_value
                end 
                focus:set_scroll(scroll)
                return true
            end
        end  
    end,
}

ac.hardware:on("鼠标滑轮滚动")(textarea.events[-1])

class.textarea = mt


return textarea